<script setup lang="ts">
import { onBeforeMount, ref, watch } from 'vue'
import ConversationContainer from './conversation/index.vue'
import NewConversation from './conversation/NewConversation.vue'
import { useDisplay } from 'vuetify'
import { useConversationStore } from '@/stores/conversation'
import { useRouter } from 'vue-router'
import Swal from 'sweetalert2'
import { useToast } from 'vue-toastification'
import type { Conversation } from '@/types'
import { useAppStore } from '@/stores/app'

const props = defineProps<{
  conversationKey: string
}>()

const router = useRouter()

const toast = useToast()
const appStore = useAppStore()
const conversationStore = useConversationStore()

const dialogShow = ref(false)
const drawShow = ref(!useDisplay().mobile.value)

const inputForm = ref()
const deleteLoading = ref('')
const hoverItem = ref('')
const editFlag = ref('')
const editValue = ref('')
const editLoading = ref('')

watch(
  () => props.conversationKey,
  (newVal) => {
    conversationStore.currentKey = newVal
  },
  { immediate: true },
)

onBeforeMount(() => {
  loadData()
})

const handleToHome = () => {
  router.push('/')
}

const handleToggleDrawShow = () => {
  drawShow.value = !drawShow.value
}

const loadData = async () => {
  await conversationStore.getConversationList()
}

const handleAddNewConversation = (inputs: object) => {
  const time = Date.now()
  const key = String(time)
  conversationStore.addConversation({
    name: '新对话',
    key,
    introduction: appStore.openingStatement,
    created_at: time,
    updated_at: time,
    inputs,
  })
  router.push(`/chats/${key}`)
}

const handleOpenInput = () => {
  if (appStore.needInputForm) {
    dialogShow.value = true
  } else {
    handleAddNewConversation({})
  }
}

const handleDialogConfirm = async () => {
  const validate = appStore.needInputForm ? await inputForm.value.validate() : true
  if (validate) {
    handleAddNewConversation(appStore.needInputForm ? inputForm.value.formData : {})
    dialogShow.value = false
  }
}

const handleEditConversation = (data: Conversation) => {
  editFlag.value = data.key
  editValue.value = data.name
}

const handleCancelEdit = () => {
  editFlag.value = ''
  editValue.value = ''
}

const handleSaveEdit = async (key: string) => {
  editLoading.value = key
  try {
    await conversationStore.renameConversation(key, editValue.value)
    toast.success('保存成功')
    handleCancelEdit()
  } finally {
    editLoading.value = ''
  }
}

const handleDeleteConversation = async (key: string) => {
  deleteLoading.value = key
  try {
    const result = await Swal.fire({
      title: '是否确认删除?',
      text: '删除后，将无法恢复此对话！',
      icon: 'warning',
      showCancelButton: true,
      confirmButtonText: '确认',
      confirmButtonColor: '#d33',
      cancelButtonText: '取消',
      cancelButtonColor: '#f6f6f6',
      reverseButtons: true,
    })
    if (result.isConfirmed) {
      await conversationStore.deleteConversation(key)
      toast.success('删除成功')
    }
  } finally {
    deleteLoading.value = ''
  }
}
</script>

<template>
  <v-navigation-drawer v-model="drawShow" class="!bg-[#f8faff] app-drawer">
    <div
      class="!p-4 border-b border-solid border-grey cursor-pointer select-none"
      @click="handleToHome"
    >
      {{ appStore.name }}
    </div>
    <div class="!p-4">
      <v-btn variant="tonal" color="primary" prepend-icon="mdi-plus" @click.stop="handleOpenInput"
        >开启新对话</v-btn
      >
    </div>
    <v-list class="!p-0 overflow-y-auto">
      <template v-for="group in Object.keys(conversationStore.groupedConversation)" :key="group">
        <v-list-subheader>{{ group }}</v-list-subheader>
        <v-list-item
          class="conversation-list-item select-none"
          :link="editFlag !== item.key"
          :to="`/chats/${String(item.key)}`"
          v-for="item in conversationStore.groupedConversation[group]"
          :key="item.key"
          @mouseenter="hoverItem = item.key"
          @mouseleave="hoverItem = ''"
        >
          <v-text-field
            v-if="editFlag === item.key"
            v-model="editValue"
            variant="outlined"
            density="compact"
            hide-details
            single-line
          ></v-text-field>
          <template v-else>{{ item.name }}</template>
          <template v-slot:append>
            <v-btn
              size="x-small"
              color="grey-lighten-1"
              icon="mdi-pencil"
              variant="text"
              v-if="hoverItem === item.key && editFlag !== item.key"
              :loading="deleteLoading === item.key"
              @click.stop.prevent="handleEditConversation(item)"
            ></v-btn>
            <v-btn
              size="x-small"
              color="grey-lighten-1"
              icon="mdi-delete"
              variant="text"
              v-if="hoverItem === item.key && editFlag !== item.key"
              :loading="deleteLoading === item.key"
              @click.stop.prevent="handleDeleteConversation(item.key)"
            ></v-btn>
            <v-btn
              size="x-small"
              color="grey-lighten-1"
              icon="mdi-check"
              variant="text"
              v-if="editFlag === item.key"
              :loading="editLoading === item.key"
              @click.stop.prevent="handleSaveEdit(item.key)"
            ></v-btn>
            <v-btn
              size="x-small"
              color="grey-lighten-1"
              icon="mdi-close"
              variant="text"
              v-if="editFlag === item.key"
              @click.stop.prevent="handleCancelEdit"
            ></v-btn>
          </template>
        </v-list-item>
      </template>
      <v-btn
        v-if="conversationStore.hasMore"
        color="#f8faff"
        block
        :loading="conversationStore.loading"
        @click.stop="loadData"
        >加载更多</v-btn
      >
    </v-list>
  </v-navigation-drawer>
  <NewConversation
    v-if="!conversationKey"
    @add-conversation="handleAddNewConversation"
    @toggle-draw-show="handleToggleDrawShow"
  />
  <ConversationContainer
    v-else-if="!conversationStore.loading"
    @toggle-draw-show="handleToggleDrawShow"
    @back-home="handleToHome"
  />
  <v-dialog v-model="dialogShow" width="60%">
    <v-card>
      <v-card-text class="!pt-[1rem]">
        <user-input-form
          ref="inputForm"
          :form-items="appStore.userInputFormItems"
        ></user-input-form>
      </v-card-text>
      <template v-slot:actions>
        <v-btn class="ms-auto" text="确认" @click="handleDialogConfirm"></v-btn>
      </template>
    </v-card>
  </v-dialog>
</template>

<style lang="scss" scoped>
.app-drawer {
  ::v-deep(.v-navigation-drawer__content) {
    display: flex;
    flex-direction: column;
  }
}
.conversation-list-item {
  ::v-deep(.v-list-item__content) {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
}
</style>
